
#define WIN32_LEAN_AND_MEAN
#include <windef.h>
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <wingdi.h>
#include <olectl.h>


/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";

#define HIMETRIC_INCH	2540        // used to convert inches to pixels

static HINSTANCE hThisInstance;                  // value of current instance
static HWND hwnd;                                // This is the handle for our window 
static MSG messages;                             // Here messages to the application are saved 
WNDCLASSEX wincl;                                // Data structure for the windowclass 
LPPICTURE gpPicture;                             // Pointer for background picture
FILE *fp_log;
UINT Timer1 = 1;

// =============================================================================
//
// This function loads a file into an IStream.
//
// =============================================================================
void LoadPictureFile()
{	
    LPVOID pvData = NULL;
	DWORD dwBytesRead = 0;
	LPSTREAM pstm = NULL;
    	
	// open file
	HANDLE hFile = CreateFile(TEXT("myimage.jpg"), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile==INVALID_HANDLE_VALUE) fprintf(fp_log,"LoadPicture CreateFile failed\n");
    fprintf(fp_log,"LoadPictureFile Open\n");
    
	// get file size
	DWORD dwFileSize = GetFileSize(hFile, NULL);
    if (dwFileSize==(-1)) fprintf(fp_log,"LoadPicture GetFileSize failed");
    fprintf(fp_log,"LoadPictureGot file size\n");

	// alloc memory based on file size
	HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
    if (hGlobal==NULL) fprintf(fp_log,"LoadPicture GlobalAlloc failed");
    fprintf(fp_log,"LoadPictureAllocated memory\n");

	pvData = GlobalLock(hGlobal);
    if (pvData==NULL) fprintf(fp_log,"LoadPicture GlobalLock failed\n");

	// read file and store in global memory
	BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
    if (bRead==FALSE) fprintf(fp_log,"LoadPicture ReadFile failed\n");
	GlobalUnlock(hGlobal);
	CloseHandle(hFile);

	// create IStream* from global memory
	HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pstm);
    if (hr!=S_OK) fprintf(fp_log,"LoadPicture CreateStreamOnHGlobal failed\n");

	// Create IPicture from image file
//	if (gpPicture) gpPicture->Release();
	hr = ::OleLoadPicture(pstm, dwFileSize, FALSE, IID_IPicture, (LPVOID *)&gpPicture);
    if (hr!=S_OK) fprintf(fp_log,"LoadPicture CreateStreamOnHGlobal failed\n");
    if (!gpPicture) fprintf(fp_log,"LoadPicture CreateStreamOnHGlobal failed 2\n");
	pstm->Release();
    fprintf(fp_log,"LoadPicture","Appears to have loaded\n");
}



// =============================================================================
//
// Paint the screen window if it has changed
//
// =============================================================================
int display_screen(void)
{
  HDC hdc,mhdc; 
  PAINTSTRUCT lpPaint;
  RECT rc,vc;
  HBITMAP hbm,oldhbm;
 
      LoadPictureFile();
      // get the device contect for the current window
      InvalidateRect(hwnd,NULL,FALSE);          // Make sure the screen refreshes
      hdc=BeginPaint(hwnd,&lpPaint);
        

         
      // output the background picture
//	  if (gpPicture)
//		{	
            // get width and height of picture
			long hmWidth;
			long hmHeight;
			gpPicture->get_Width(&hmWidth);
			gpPicture->get_Height(&hmHeight);
			// convert himetric to pixels
			int nWidth	= MulDiv(hmWidth, GetDeviceCaps(hdc, LOGPIXELSX), HIMETRIC_INCH);
			int nHeight	= MulDiv(hmHeight, GetDeviceCaps(hdc, LOGPIXELSY), HIMETRIC_INCH);

			mhdc = CreateCompatibleDC(hdc); 
            hbm = CreateCompatibleBitmap ( hdc, nWidth, nHeight );
            oldhbm = (HBITMAP) SelectObject(mhdc,hbm);

			// display picture using IPicture::Render
			gpPicture->Render(mhdc, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, &rc);
//		  }
//
      // Copy the memory DC to the screen then release the memory objects
      BitBlt(hdc,0,0,nWidth,nHeight,mhdc,0,0,SRCCOPY);
      hbm = (HBITMAP) SelectObject(mhdc,oldhbm);
//      if ((hbm==NULL) || (hbm==HGDI_ERROR)) { mylog_error("Error from SelectObject(hbm)"); }
//      if (DeleteObject(hbm)==0) { mylog_error("Error from DeleteObject(hbm)"); }
//      if (DeleteObject(mhdc)==0) { mylog_error("Error from DeleteObject(mhdc)"); }
      EndPaint(hwnd,&lpPaint);
      ShowWindow (hwnd, SW_RESTORE);
//    }
  return 1;
}


    
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{

    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    if ((fp_log=fopen("DisplayJpg.log","a"))==NULL) fprintf(fp_log,"Failed to open ini file");
    fprintf(fp_log,"started\n");
    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
 //          "Windows App",       /* Title Text */
 //          WS_OVERLAPPEDWINDOW, /* default window */
             NULL,
             WS_POPUPWINDOW,
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           800,                 /* The programs width */
           400,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);
//    LoadPictureFile();
    display_screen();
    if (SetTimer(hwnd, Timer1, 1000, (TIMERPROC) NULL)==0) fprintf(fp_log,"eek\n");
    
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {    // display_screen();
         fprintf(fp_log, "Message %d\n",messages.message);
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {            fprintf(fp_log, "Callback Message %d\n",messages.message);
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        case WM_TIMER:
//             SetTimer(hwnd, Timer1, 1000, (TIMERPROC) NULL);
        case WM_PAINT:
             display_screen();
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
